package org.jparrow.framework.proxy;

import java.lang.reflect.Method;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 切面代理
 * 
 * 模板方法模式（钩子方法）：
 * 		将需要的具体实现交给子类去继承，实现。
 * 
 * @author supda
 * @Date 2017-3-29 上午10:06:49
 *
 */
public abstract class AspectProxy implements Proxy{

	private static final Logger logger = LoggerFactory.getLogger(AspectProxy.class);
	
	//代理执行
	@Override
	public Object doProxy(ProxyChain proxyChain) throws Throwable {

		Object result = null;
		
		Class<?> cls = proxyChain.getTargetClass();
		Method method = proxyChain.getTargetMethod();
		Object[] params = proxyChain.getMethodParams();
		
		begin();
		
		try{
			if(interceptor(cls, method, params)){
				before(cls, method, params);
				result = proxyChain.doProxyChain();
				after(cls, method, params, result);
			}else{
				result = proxyChain.doProxyChain();
			}
		}catch(Exception e){
			logger.error("proxy failure", e);
			error(cls, method, params, e);
			throw e;
		}finally{
			end();
		}
		
		return result;
	}
	
	public void begin() {
		
	}

	/**
	 * 是否代理
	 */
	public boolean interceptor(Class<?> cls, Method method, Object[] params) {
		return true;
	}

	/**
	 * 前置通知
	 */
	public void before(Class<?> cls, Method method, Object[] params) {

	}

	/**
	 * 后置通知
	 */
	public void after(Class<?> cls, Method method, Object[] params,
			Object result) {
	}

	/**
	 * 异常通知
	 */
	public void error(Class<?> cls, Method method, Object[] params, Exception e) {
	}

	/**
	 * finally增强
	 */
	public void end() {
	}

}
